package com.autobet.utils;

import org.apache.log4j.Logger;
/**
 * Created by yangd on 2017-08-27.
 */
public class IdGenerator {

    private static Logger logger = Logger.getLogger(IdGenerator.class);
    private static long primarykeyId;
    private static final long twepoch = 1417834194351L;
    private static long sequence = 0L;
    private static final long primarykeyIdBits = 10L;
    private static final long sequenceBits = 10L;
    private static final long primarykeyIdBitsShift = 10L;
    private static final long timestampLeftShift = 20L;
    private static long lastTimestamp = -1L;
    public static final long sequenceMask = 1023L;
    public static final long maxWorkerId = 1023L;

    public IdGenerator(long primarykeyId) {
        if(primarykeyId <= 1023L && primarykeyId >= 0L) {
            primarykeyId = primarykeyId;
        } else {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", new Object[]{Long.valueOf(1023L)}));
        }
    }

    public static synchronized String getId() {
        return Long.toHexString(nextId()).toUpperCase();
    }

    public static synchronized String getSLId() {
        return String.valueOf(nextId());
    }

    public static synchronized Long getLId() {
        return Long.valueOf(nextId());
    }

    private static long nextId() {
        long timestamp = timeGen();
        if(lastTimestamp == timestamp) {
            sequence = sequence + 1L & 1023L;
            if(sequence == 0L) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        if(timestamp < lastTimestamp) {
            try {
                throw new Exception(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", new Object[]{Long.valueOf(lastTimestamp - timestamp)}));
            } catch (Exception var4) {
                logger.error("[IdGenerator] [nextId] error:" + var4.getMessage(), var4);
            }
        }

        lastTimestamp = timestamp;
        long nextId = timestamp - 1417834194351L << 20 | primarykeyId << 10 | sequence;
        return nextId;
    }

    private static long tilNextMillis(long lastTimestamp) {
        long timestamp;
        for(timestamp = timeGen(); timestamp <= lastTimestamp; timestamp = timeGen()) {
            ;
        }

        return timestamp;
    }

    private static long timeGen() {
        return System.currentTimeMillis();
    }
}
